/*
*    Phantom Test Driver v2.0 GUI Automation Software
*    Copyright (C) 2009  John C. Van Arsdall (john@phantomtest.com)
*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License along
*    with this program; if not, write to the Free Software Foundation, Inc.,
*    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
/*
 * PTDSuiteDisplay.java
 *
 * Created on May 14, 2008, 6:15 PM
 */

package ptd;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Vector;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyledDocument;
import javax.swing.text.StyleConstants;
/**
 *
 * @author  John
 */
public class PTDSuiteDisplay extends javax.swing.JPanel {
    public Cursor ptrCursor;
    public Cursor nomCursor;
    public Vector<PTDSuiteDisplay> Displays;
    public String my_Name;
    public PTDSuiteDisplay pD;
    public PTDSuiteDisplay preProc;
    public PTDSuiteDisplay postProc;
    
    public static Color ErrColor = Color.RED;
    public static Color WarnColor = new Color(160, 160, 0);
    
    public PTDRemoteMachine Machine = null;
    
    //public JTextPane SuiteOutput;
    
    public class OutputWheelListener implements MouseWheelListener{
        public void mouseWheelMoved(MouseWheelEvent e) {
            Main.getMainFrame().getActiveOutputPane().dispatchEvent(e);
        }
    }
    
    public class PageKeyAdapter extends KeyAdapter{
        public void keyPressed(java.awt.event.KeyEvent evt) {
            processPage(evt);
        }
        
        public void processPage(java.awt.event.KeyEvent evt){
            
            if(evt.getKeyCode() == evt.VK_PAGE_DOWN){
                Rectangle R = Main.getMainFrame().getActiveOutputPane().getVisibleRect();
                Dimension D = Main.getMainFrame().getActiveOutputPane().getSize();
                R.y = R.y + R.height;
                if(R.y > D.height){
                    R.y = D.height;
                }
                Main.getMainFrame().getActiveOutputPane().scrollRectToVisible(R);            
                return;
            }

            if(evt.getKeyCode() == evt.VK_PAGE_UP){
                Rectangle R = Main.getMainFrame().getActiveOutputPane().getVisibleRect();
                Dimension D = Main.getMainFrame().getActiveOutputPane().getSize();
                R.y = R.y - R.height;
                if(R.y < 0){
                    R.y = 0;
                }
                Main.getMainFrame().getActiveOutputPane().scrollRectToVisible(R);
                return;
            }
        }
    }
    /*
        C.addKeyListener(new java.awt.event.KeyAdapter() {
        });     
     * */
    
    /** Creates new form PTDSuiteDisplay */
    public PTDSuiteDisplay() {
        initComponents();      
        preProc = null;
        postProc = null;
        
        //SuiteOutput = new JTextPane();
        
        // Must be done for printing purposes
        TestcaseOutput.setFont(new Font("Courier New", 0, 12));
  
        Displays = new Vector<PTDSuiteDisplay>();
        ErrCnt = 0;
        WarnCnt = 0;
        bInputAvailable = false;
        bCanGetInput = false;
        bCmdLock = true;
        lineAvailableCount = 0;
        pD = null;
        my_Name = "";
        
        ptrCursor = new Cursor(Cursor.HAND_CURSOR);
        nomCursor = new Cursor(Cursor.DEFAULT_CURSOR);
        Toggle.setCursor(ptrCursor);
        ErrWarn.setCursor(nomCursor);
        Label.setCursor(nomCursor);
        BlankLabel.setCursor(nomCursor);

        //SuiteOutput.setEditable(false);
        //SuiteOutput.setAutoscrolls(false);
        //SuiteOutput.setMargin(new java.awt.Insets(0, 0, 0, 0));
        //SuiteOutput.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        
        StyledDocument aDoc = TestcaseOutput.getStyledDocument();
        SimpleAttributeSet para = new SimpleAttributeSet();        
        StyleConstants.ParagraphConstants.setLeftIndent(para, 25.0f);        
        aDoc.setParagraphAttributes(0, 0, para, true);
        
        addListeners(TestcaseOutput);
        
        //addListeners(SuiteOutput);
        

        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                consumeKeys(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                consumeKeys(evt);
            }
            
            public void keyReleased(java.awt.event.KeyEvent evt) {
                consumeKeys(evt);
            }
        });       

        OutputWheelListener aListener = new OutputWheelListener();
        addMouseWheelListener(aListener);
        ErrWarn.addMouseWheelListener(aListener);
        TestcaseOutput.addMouseWheelListener(aListener);
        Toggle.addMouseWheelListener(aListener);
        Label.addMouseWheelListener(aListener);
        BlankLabel.addMouseWheelListener(aListener);
        
        PageKeyAdapter Adapter = new PageKeyAdapter();
        addKeyListener(Adapter);
        ErrWarn.addKeyListener(Adapter);
        TestcaseOutput.addKeyListener(Adapter);
        Toggle.addKeyListener(Adapter);
        Label.addKeyListener(Adapter);
        BlankLabel.addKeyListener(Adapter);
        
        //Toggle.setText(" + ");
        //OutputScroll.setVisible(false);
        
        Toggle.setText(" - ");
        OutputScroll.setVisible(true);
        
        //TestcaseOutput.setText("");
        //SuiteOutput.setText("");
        validate();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        Label = new javax.swing.JLabel();
        OutputScroll = new javax.swing.JScrollPane();
        TestcaseOutput = new javax.swing.JTextPane();
        Toggle = new javax.swing.JLabel();
        BlankLabel = new javax.swing.JLabel();
        ErrWarn = new javax.swing.JLabel();

        setBackground(new java.awt.Color(255, 255, 255));
        setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
        });
        setLayout(new java.awt.GridBagLayout());

        Label.setBackground(new java.awt.Color(255, 255, 255));
        Label.setFont(new java.awt.Font("Arial", 1, 18)); // NOI18N
        Label.setText("lala");
        Label.setAlignmentX(0.5F);
        Label.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        Label.setInheritsPopupMenu(false);
        Label.setOpaque(true);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 0, 0);
        add(Label, gridBagConstraints);

        OutputScroll.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        OutputScroll.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        OutputScroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

        TestcaseOutput.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        TestcaseOutput.setFont(new java.awt.Font("Angsana New", 0, 12)); // NOI18N
        TestcaseOutput.setAutoscrolls(false);
        TestcaseOutput.setMargin(new java.awt.Insets(0, 0, 0, 0));
        OutputScroll.setViewportView(TestcaseOutput);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        gridBagConstraints.weighty = 1.0;
        add(OutputScroll, gridBagConstraints);

        Toggle.setFont(new java.awt.Font("Courier New", 1, 14));
        Toggle.setText(" - ");
        Toggle.setToolTipText("Click to toggle output display.");
        Toggle.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0), 2));
        Toggle.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                ToggleMouseClicked(evt);
            }
        });
        Toggle.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                ToggleMouseMoved(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        add(Toggle, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        add(BlankLabel, gridBagConstraints);

        ErrWarn.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
        ErrWarn.setText("0 Errors, 0 Warnings");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        add(ErrWarn, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents

    private void ToggleMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_ToggleMouseMoved
        //setCursor(ptrCursor);
    }//GEN-LAST:event_ToggleMouseMoved

    private void ToggleMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_ToggleMouseClicked
        //formMouseClicked(evt);
        if(OutputScroll.isVisible()){
            Toggle.setText(" + ");
            OutputScroll.setVisible(false);
            //OutputScroll.updateUI();
            //TestcaseOutput.updateUI();
            //validate();
        }else{
            Toggle.setText(" - ");
            OutputScroll.setVisible(true);
            //OutputScroll.updateUI();
            //Output.updateUI();
            //validate();
        }
    }//GEN-LAST:event_ToggleMouseClicked

    private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked
        /*
        if(OutputScroll.isVisible()){
            Toggle.setText(" + ");
            OutputScroll.setVisible(false);
            //OutputScroll.updateUI();
            //TestcaseOutput.updateUI();
            //validate();
        }else{
            Toggle.setText(" - ");
            OutputScroll.setVisible(true);
            //OutputScroll.updateUI();
            //Output.updateUI();
            //validate();
        }
         **/
    }//GEN-LAST:event_formMouseClicked
        
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel BlankLabel;
    private javax.swing.JLabel ErrWarn;
    public javax.swing.JLabel Label;
    private javax.swing.JScrollPane OutputScroll;
    public javax.swing.JTextPane TestcaseOutput;
    private javax.swing.JLabel Toggle;
    // End of variables declaration//GEN-END:variables
    
    public int ErrCnt;
    public int WarnCnt;
    public int SegmentPosition;
    public boolean bCmdLock;
    public boolean bCanGetInput;
    public boolean bInputAvailable;
    public int lineAvailableCount;

    
    
    public void addError(){
        ErrCnt = ErrCnt + 1;
        String s = Integer.toString(ErrCnt) + " Errors, " + Integer.toString(WarnCnt) + " Warnings";
        ErrWarn.setForeground(ErrColor);
        ErrWarn.setText(s);
    }
    
    public void addWarn(){
        WarnCnt = WarnCnt + 1;
        String s = Integer.toString(ErrCnt) + " Errors, " + Integer.toString(WarnCnt) + " Warnings";
        if(ErrCnt > 0){
            ErrWarn.setForeground(ErrColor);
        }else{
            ErrWarn.setForeground(WarnColor);
        }
        ErrWarn.setText(s);
    }

    public String getInput(){
        bCmdLock = true;
        Document aDoc = TestcaseOutput.getDocument();
        String Ret = "";
        try{
            Ret = aDoc.getText(SegmentPosition, aDoc.getLength() - SegmentPosition);
            SegmentPosition = aDoc.getLength();
        }catch (Exception e){
            Main.debug_out(e.getMessage());
        }
        
        int i = Ret.indexOf("\n", 0);
        if(i >= 0){
            Ret = Ret.substring(0, i);
        }
        
        bInputAvailable = false;
        bCanGetInput = false;
        TestcaseOutput.setBackground(Color.WHITE);
        
        return Ret;
    }
    
    
    public void setExpanded(boolean b){
        if(!b){
            Toggle.setText(" + ");
            OutputScroll.setVisible(false);
        }else{
            Toggle.setText(" - ");
            OutputScroll.setVisible(true);
        }
        validate();
        repaint();
        ErrWarn.validate();
        ErrWarn.repaint();
        
    }
    
    public void consumeKeys(java.awt.event.KeyEvent evt){
        if(evt.getKeyCode() == evt.VK_LEFT){
                    return;
                }
                
                if(evt.getKeyCode() == evt.VK_RIGHT){
                    return;
                }
                
                if(evt.getKeyCode() == evt.VK_UP){
                    return;
                }
                
                if(evt.getKeyCode() == evt.VK_DOWN){
                    return;
                }
                
                if(evt.getKeyCode() == evt.VK_PAGE_DOWN){
                    return;
                }
                if(evt.getKeyCode() == evt.VK_PAGE_UP){
                    return;
                }
        
        
        evt.consume();
    }
        
    public void detectInput(java.awt.event.KeyEvent evt){
        if(evt.isControlDown()){
            // Prevent paste
            if((evt.getKeyCode() == evt.VK_V) && bCmdLock){
                evt.consume();
            }
            // Dont want to consume event if control is pressed, yo...
            return;
        }

        if(evt.isAltDown()){
            // Dont want to consume event if alt is pressed, yo...
            return;
        }
        
        if(evt.getKeyCode() == evt.VK_PAGE_DOWN){
            return;
        }
        
        if(evt.getKeyCode() == evt.VK_PAGE_UP){
            return;
        }

        if(evt.getKeyCode() == evt.VK_UP){
            return;
        }

        if(evt.getKeyCode() == evt.VK_DOWN){
            return;
        }
        
        if(evt.getKeyCode() == evt.VK_LEFT){
            return;
        }
        
        if(evt.getKeyCode() == evt.VK_RIGHT){
            return;
        }
        
        if(evt.getKeyCode() == evt.VK_SHIFT){
            return;
        }

        if(bCmdLock){
            evt.consume();
        }
        
        int CurrPos = TestcaseOutput.getSelectionStart();
        
        if(evt.getKeyCode() == evt.VK_ENTER){                
            if(bCanGetInput){
                //evt.consume();
                TestcaseOutput.setCaretPosition(TestcaseOutput.getDocument().getLength());
                bInputAvailable = true;
            }else{
                bInputAvailable = false;
            }        
        }else if(evt.getKeyCode() == evt.VK_UP){
        }else if(evt.getKeyCode() == evt.VK_DOWN){
        }else if(evt.getKeyCode() == evt.VK_LEFT){
            if(CurrPos <= SegmentPosition){
                evt.consume();
            }
            // Check against minimum location
        }else if(evt.getKeyCode() == evt.VK_HOME){
            evt.consume();
            TestcaseOutput.setCaretPosition(SegmentPosition);
        }else if(evt.getKeyCode() == evt.VK_BACK_SPACE){
            if(CurrPos <= SegmentPosition){
                evt.consume();
            }
        }
            
        if(CurrPos < SegmentPosition){
            TestcaseOutput.setCaretPosition(TestcaseOutput.getDocument().getLength());
        }
    }
    
    // -----------------------------------------------------
    public boolean lineAvailable(){
        // bCanGetInput is checked in PTFHTMLPane lineAvailable as a first time through flag as well
        if(bCanGetInput == false){
            bCanGetInput = true;
            lineAvailableCount = 0;
            bCmdLock = false;
            TestcaseOutput.requestFocus();
            TestcaseOutput.setBackground(new Color(255, 190, 200));
            TestcaseOutput.setCaretPosition(TestcaseOutput.getDocument().getLength());
        }
        
        // Do this to force scroll to visible in PTDHTMLPane
        if(lineAvailableCount < 2){
            lineAvailableCount = lineAvailableCount + 1;
        }
        return bInputAvailable;
    }
    
   // -----------------------------------------------------
    public void addText(String newText, SimpleAttributeSet Attr){
        try{
            Document aDoc = TestcaseOutput.getDocument();
            
            //StyledDocument aDoc = TestcaseOutput.getStyledDocument();
            aDoc.insertString(aDoc.getLength(), newText, Attr);
            SegmentPosition = aDoc.getLength();
            
            
            //Rectangle R = new Rectangle();
            //Dimension D = Main.getMainFrame().getActiveOutputPane().getSize();
            //R.y = D.height-5;
            //R.x = 1;
            //R.width = 1;
            //R.height = 1;
            //Main.getMainFrame().getActiveOutputPane().scrollRectToVisible(R);
            
            //Output.validate();
            //validate();
        }catch (Exception e){
            Main.debug_out(e.getMessage());
        } 
    }
    
    // -----------------------------------------------------
    public int getChildCount(){
        return Displays.size();
    }
    
    // -----------------------------------------------------
    public PTDSuiteDisplay getChildAt(int index){
        if(index >= Displays.size()){
            return null;
        }
        return Displays.get(index);
    }

    // -----------------------------------------------------
    public int getErrCnt() {
        return ErrCnt;
    }

    // -----------------------------------------------------
    public int getWarnCnt() {
        return WarnCnt;
    }
    
    // -----------------------------------------------------
    public String getOutput(){
        String s = TestcaseOutput.getText();
        return s;
    }
    
    
    // -----------------------------------------------------
    public PTDSuiteDisplay getParentDisplay(){
        return pD;
    }
    
    // -----------------------------------------------------
    public boolean saveAsText(String sFileName){
        return saveOutput(sFileName, 0);
    }

    // -----------------------------------------------------
    public boolean saveAsHTML(String sFileName){
        return saveOutput(sFileName, 1);
    }
    
    // -----------------------------------------------------
    public boolean hasParentDisplay(){
        if(pD == null){
            return false;
        }
        return true;
    }    

    // -----------------------------------------------------
    public String getName(){
        return my_Name;
    }
    

    // -----------------------------------------------------
    public void setRunning(boolean bRunning){
        if(bRunning){
            Label.setBackground(new Color(200, 220, 255));
        }else{
            Label.setBackground(Color.WHITE);
        }
    }
    
    // -----------------------------------------------------
    public void addDisplay(PTDSuiteDisplay In){
        In.pD = this;
        Displays.add(In);
    }
    
    // -----------------------------------------------------
    public int computePrintBackoff(int startLoc, int endLoc){
        // endloc must be absolute (from start of display) or else
        // the contains method may not work properly
        // Oh, but it is...
        
        int diff = 0;
        if(Displays.size() > 0){
            
            endLoc = endLoc - OutputScroll.getY();  // Adjust for offset to get to start of Output
            startLoc = startLoc - OutputScroll.getY();  // Adjust for offset to get to start of Output
            
            for(int i = 0; i < Displays.size(); i++){
                PTDSuiteDisplay D = Displays.get(i);
                if(D == null){
                    return 0;
                }

                diff = checkDisplayPrint(D, endLoc, startLoc);
                if(diff >= 0){
                    return diff;
                }
            }
        }
        
        Main.debug_out(my_Name + " contains the point!");
        
        int W = Label.getWidth()/2;
        printInfo(Label, my_Name+"-Label", W, endLoc-Label.getY());
        if(Label.contains(W, endLoc-Label.getY())){
            Main.debug_out("Label Diff");
            return endLoc - (Label.getY());
        }
        
        W = ErrWarn.getWidth()/2;
        printInfo(ErrWarn, my_Name+"-ErrWarn", W, endLoc-ErrWarn.getY());
        if(ErrWarn.contains(W, endLoc-ErrWarn.getY())){
            Main.debug_out("ErrWarn Diff");
            return endLoc - (ErrWarn.getY());
        }
        
        W = OutputScroll.getWidth()/2;
        int delta = OutputScroll.getY();
        //if(startLoc <= 0){
        endLoc = endLoc - delta;     
        startLoc = startLoc - delta;

        
        if(preProc != null){
            diff = checkDisplayPrint(preProc, endLoc, startLoc);
            if(diff >= 0){
                return diff;
            }
        }

        if(postProc != null){
            diff = checkDisplayPrint(postProc, endLoc, startLoc);
            if(diff >= 0){
                return diff;
            }
        }
        
        // If it isnt in preproc, and isnt in postproc, should be either in text
        // section or nowhere, so leave it be
        
        //}
        //startLoc = startLoc - delta;  We dont want this... total dist should decrease
        printInfo(OutputScroll, my_Name+"-Output", startLoc, endLoc);
        if(OutputScroll.contains(W, endLoc)){
            int dist = 0;            
            if(OutputScroll.contains(W, startLoc)){
                dist = (endLoc - startLoc) + 1;
                //dist = (endLoc - startLoc);
            }else{
                dist = endLoc + 1;
                //dist = endLoc;
            }
            
            if(preProc != null){
                dist = dist - preProc.getHeight();
            }
            
            Font F = TestcaseOutput.getFont();
            Main.debug_out("Font: " + F.getFamily());
            int i = F.getSize();
            int LH = TestcaseOutput.getFontMetrics(F).getHeight();
            
            int numLines = dist/LH;
            
            Main.debug_out("numLines: " + Integer.toString(numLines) + " dist:" + Integer.toString(dist));
            diff = dist-(numLines*LH);
            Main.debug_out("Diff: " + Integer.toString(diff));
            return diff;            
        }
        Main.debug_out("No Diff Calced");
        return 0;
    }
    
    // -----------------------------------------------------
    public void printInfo(Container D, String Name, int s, int e){
        String sBounds = Integer.toString(D.getX()) + "," + Integer.toString(D.getY()) + "," +Integer.toString(D.getWidth()) + "," + Integer.toString(D.getHeight());
        Main.debug_out("Looking in: " + Name + " Search:" + Integer.toString(s) + "," + Integer.toString(e) + " Bounds:" + sBounds);        
    }
    
    // -----------------------------------------------------
    public int checkDisplayPrint(PTDSuiteDisplay D, int endLoc, int startLoc){
        String sBounds = Integer.toString(D.getParent().getX()) + "," + Integer.toString(D.getParent().getY()) + "," +Integer.toString(D.getParent().getWidth()) + "," + Integer.toString(D.getParent().getHeight());

        int w = (int)(D.getParent().getWidth()/2);
        int e = endLoc - D.getParent().getY();  // Adjust for offset to get to start of display
        int s = startLoc - D.getParent().getY();
        
        if(D.getParent().contains(w, e)){       // Check if display contains the point
            Main.debug_out("Looking in: " + D.my_Name + " Search:" + Integer.toString(w) + "," + Integer.toString(e) + " Bounds:" + sBounds);
            return D.computePrintBackoff(s, e);
        }else{
            Main.debug_out("Looked in: " + D.my_Name + " Search:" + Integer.toString(w) + "," + Integer.toString(e) + " Bounds:" + sBounds);
            return -1;
        }
    }

    // -----------------------------------------------------
    public void addListeners(Container C){
        C.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                detectInput(evt);
            }
            public void keyTyped(java.awt.event.KeyEvent evt) {
                detectInput(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                detectInput(evt);
            }
        });               
    }

    // -----------------------------------------------------
    public void setSuite(boolean bState){
        if(bState){
            //OutputScroll.setViewportView(SuiteOutput);
        }
    }
    
    // -----------------------------------------------------
    public void collapseAll(){
        if(Displays.size() > 0){
            for(int i = 0; i < Displays.size(); i++){
                PTDSuiteDisplay D = Displays.get(i);
                D.collapseAll();
            }
        }
        if(preProc != null){
            preProc.collapseAll();
        }
        if(postProc != null){
            postProc.collapseAll();
        }
        
        
        setExpanded(false);
    }
    
    // -----------------------------------------------------
    public void expandAll(){
        if(Displays.size() > 0){
            for(int i = 0; i < Displays.size(); i++){
                PTDSuiteDisplay D = Displays.get(i);
                D.expandAll();
            }
        }        
        if(preProc != null){
            preProc.expandAll();
        }
        if(postProc != null){
            postProc.expandAll();
        }
        
        setExpanded(true);
    }
    
    // -----------------------------------------------------
    public void export(OutputStreamWriter aWriter, int Type, String Spaces, int ctr, boolean isProc) throws Exception{
        String nl = System.getProperty("line.separator");
        String sID = "ID_" + Integer.toString(ctr);
        ctr = ctr + 1;
        if(Type == 0){
            aWriter.write(Spaces + Label.getText());
            aWriter.write(nl);
        }else{
            aWriter.write("<!-- ---------- " + my_Name + " BEGIN ----------------------- -->" + nl);
            String sBGCOLOR = "\"#FFFFFF\"";
            if(isProc){
                sBGCOLOR = "\"#E5E5E5\"";
            }
            aWriter.write("<table border=\"0\" cellspacing=\"0\" width=100%><tr><td colspan=2 bgcolor=" + sBGCOLOR + ">");
            aWriter.write(nl);
            //aWriter.write("<div class='toggle' onClick=toggle("+sID+")>Toggle</div>\n");
            
            aWriter.write("<font size = \"5\"><strong>");
            
            
            aWriter.write(Label.getText());
            aWriter.write("</strong></font>");
            aWriter.write("</td></tr>");
            aWriter.write(nl);
        }
        //if(preProc != null){
        //    if(Type == 1){
        //        aWriter.write("<tr><td colspan=2>");
        //        aWriter.write(nl);
        //        preProc.export(aWriter, Type, Spaces, ctr = ctr + 1);
        //        aWriter.write("</td></tr>");
        //        aWriter.write(nl);
        //    }else{
        //        preProc.export(aWriter, Type, Spaces, ctr = ctr + 1);
        //    }
        //}
        if(Displays.size() > 0){
            if(Type == 1){
                aWriter.write("<tr><td width=5%></td><td>");
                //aWriter.write("<p id='" + sID + "' class='hidden'>");
                aWriter.write(nl);
                
            }
            if(preProc != null){
                preProc.export(aWriter, Type, Spaces, ctr = ctr + 1, true);
            }
            for(int i = 0; i < Displays.size(); i++){
                Displays.get(i).export(aWriter, Type, Spaces + "   ", ctr = ctr + 1, false);
            }
            if(postProc != null){
                postProc.export(aWriter, Type, Spaces, ctr = ctr + 1, true);
            }
            if(Type == 1){
                //aWriter.write("</p></td></tr>");
                aWriter.write("</td></tr>");
                aWriter.write(nl);
            }

        }else{
            String s = TestcaseOutput.getText();
            if(Type == 0){
                s = s.replaceAll("\n", "\n"+Spaces);
                s = Spaces + s;
                if(preProc != null){
                    preProc.export(aWriter, Type, Spaces, ctr = ctr + 1, true);
                }
                aWriter.write(s + nl);
                if(postProc != null){
                    postProc.export(aWriter, Type, Spaces, ctr = ctr + 1, true);
                }

            }else{
            
                aWriter.write("<tr><td width=5%></td><td colspan=2 bgcolor=\"#FFFFFF\">" + nl);
                //aWriter.write("<p id='" + sID + "' class='hidden'>");
                //aWriter.write("<p id='" + sID + ">");
                aWriter.write(nl);
                if(preProc != null){
                    preProc.export(aWriter, Type, Spaces, ctr = ctr + 1, true);
                }

                s = s.replaceAll("<", "&lt");
                s = s.replaceAll(">", "&gt");
                s = s.replaceAll("\n", "<br>\n");
                aWriter.write(s + nl);
                if(postProc != null){
                    postProc.export(aWriter, Type, Spaces, ctr = ctr + 1, true);
                }
                
                //aWriter.write("</p></td></tr>");
                aWriter.write("</td></tr>");
                aWriter.write(nl);
                
            }
            
        }
        //if(postProc != null){
        //    if(Type == 1){
        //        aWriter.write("<tr><td colspan=2>");
        //        aWriter.write(nl);
        //        postProc.export(aWriter, Type, Spaces, ctr = ctr + 1);
        //        aWriter.write("</td></tr>");
        //        aWriter.write(nl);
        //    }else{
        //        postProc.export(aWriter, Type, Spaces, ctr = ctr + 1);
        //    }
        //}
        if(Type == 0){
            aWriter.write(Spaces + ErrWarn.getText());
            aWriter.write(nl);
        }else{
            aWriter.write("<tr><td colspan=2>");
            aWriter.write(nl);            
            String sColor = "000000";
            String StrongStart = "";
            String StrongEnd = "";
            
            if(getErrCnt() > 0){
                sColor = Integer.toString(ErrColor.getRed(), 16).toUpperCase();
                sColor = sColor + Integer.toString(ErrColor.getGreen(), 16).toUpperCase();
                sColor = sColor + Integer.toString(ErrColor.getBlue(), 16).toUpperCase();
                StrongStart = "<strong>";
                StrongEnd = "</strong>";
            }else if(getWarnCnt() > 0){
                sColor = Integer.toString(WarnColor.getRed(), 16).toUpperCase();
                sColor = sColor + Integer.toString(WarnColor.getGreen(), 16).toUpperCase();
                sColor = sColor + Integer.toString(WarnColor.getBlue(), 16).toUpperCase();
                StrongStart = "<strong>";
                StrongEnd = "</strong>";
                
            }
            sColor = "\"#" + sColor + "\"";
            aWriter.write("<font color = " + sColor + ">" + StrongStart);
            aWriter.write(nl);            
            aWriter.write(ErrWarn.getText());
            aWriter.write(nl);
            aWriter.write(StrongEnd + "</font></td></tr></table>");
            aWriter.write(nl);
            aWriter.write("<!-- oooooooooo " + my_Name + " END oooooooooooooooooooooo -->" + nl);
        }
    }

    // -----------------------------------------------------

    public boolean saveOutput(String sPath, int Type){
        // -----------------------------------------------------
        try{
            // This is how we write
            File aFile = new File(sPath);
            FileOutputStream anOutput = new FileOutputStream(aFile);
            OutputStreamWriter aWriter = new OutputStreamWriter(anOutput);
            if(Type == 1){
                aWriter.write("<HTML><HEAD><TITLE>PTD Output</TITLE>\n");
                //aWriter.write("<style>\n.toggle{cursor:pointer;}\n.hidden{display:none;}\n.shown{display:block;\nwhite-space: nowrap;\n}\n</style>\n");
                aWriter.write("</HEAD>\n");
                //aWriter.write("<script language='JavaScript'>\n<!--\nfunction toggle(section_name){\nif(section_name.className.match('hidden')){\nsection_name.className = 'shown';\n}else{\nsection_name.className = 'hidden';\n}\n}\n//-->\n</SCRIPT>\n");
                aWriter.write("<BODY>\n");
                aWriter.write("<font face = \"Courier New\">\n");
            }
            export(aWriter, Type, "", 0, false);
            if(Type == 1){
                aWriter.write("</font>");
                aWriter.write("</BODY></HTML>\n");
            }

            aWriter.flush();
            aWriter.close();
            
        }catch (Exception e){
            Main.debug_out(e.getMessage());
            return false;
        }
        return true;
    }
    
    public String getRemoteMachine(){
        if(Machine != null){
            return Machine.myName;
        }else{
            return "";
        }
    } 
    
    public void haltExecution(){
        if(Machine != null){
            Machine.runState = false;
        }else{
            Main.getMainFrame().setSuiteRunning(false);
        }
    } 
}

